Exposing asynchronous services
Exposing BizTalk
processes through asynchronous channels is also a clear-cut task. Once
again, you cannot expose WCF service from BizTalk that have the isOneWay attribute set to True. There is no option in the BizTalk WCF Service Publishing Wizard to do so. However, because of the loosely coupled nature of BizTalk's messaging engine, a straightforward void service behaves in a similar fashion to a true one-way service.
Let's start out with a very
basic orchestration that takes in our canonical Adverse Event schema
and then purposely causes an exception. In my case, I perform a "divide
by zero" calculation. Notice that one-way orchestration receive ports
do not have the option to attach a Fault Message.
On two-way ports, because we know the caller is expecting a response,
we can define a specific fault message to return instead of expected
result data.
Once our BizTalk project is redeployed, we should walk through the BizTalk WCF Service Publishing Wizard in order to produce a service on-ramp for this orchestration. Construct a new service and endpoint for the WCF-WSHttp adapter and manually assemble the service contract by choosing the Publish schemas as WCF service option.
Now this service is
technically a request/response service. We can verify this by looking
at the resulting WSDL for the service and observing that our PublishNewAE
operation has both a request and response message. However, it is
critical to understand that as far as the service is concerned, its
operation is completed when the message reaches the MessageBox, not
after (all) subscribers are done with it. Therefore, the service client
only needs to wait until the message is published and is not impacted
by actions of downstream subscribers.
To prove this, all we have
to do is call this service. Before we can do that, let's bind our
orchestration to the receive port that was auto-generated by the BizTalk WCF Service Publishing Wizard.
After starting the receive location and orchestration, we can reference
this service from our previously-built console client application.
Let's add a new Service Reference
to the console application and point to the fresh WCF service we just
built (if you so desire, nothing prevents you from choosing the
advanced option of generating client-asynchronous proxy objects). We
can call this service just like any other WCF service:
private static void CallBizTalkSyncService()
{
Console.WriteLine("Calling BizTalk sync service ...");
AdverseEventServiceClient client = new AdverseEventServiceClient ("BizTalkAESyncEndpoint");
try
{
BizTalkAdverseEvent newAE = new BizTalkAdverseEvent();
newAE.PatientID = "100912";
newAE.PhysicianID = "7543";
newAE.Product = "Cerinob";
newAE.ReportedBy = "Patient";
newAE.Category = "Injection Soreness";
newAE.DateStarted = new DateTime(2008, 10, 29).ToShortDateString();
client.SubmitNewAdverseEvent(newAE);
Console.WriteLine("Service result returned ...");
client.Close();
Console.ReadLine();
}
catch (System.ServiceModel.CommunicationException) { client.Abort(); }
catch (System.TimeoutException) { client.Abort(); }
catch (System.Exception) { client.Abort(); throw; }
}
Sure enough, the
service completes successfully, while the BizTalk Administration
Console reveals a suspended orchestration resulting from the
orchestration exception. So if subscriber exceptions don't flow back to
the client application, does that mean that nothing bubbles back to
this WCF client as a result of an asynchronous service invocation? What
you'll find is that any error encountered while physically publishing
the message results in an exception flowed back to the client. For
instance, if the web site hosting the service is unavailable, or a
receive location is offline, you will see that error in the client
application. If no subscribers are found, or a subscriber has any issue
processing the message, these errors stay local to the BizTalk Server.
So while BizTalk
does not expose truly asynchronous services, the fact that the service
operation only extends to MessageBox publication means that in essence,
the messages are of a "fire-and-forget" fashion. How the messages are
processed is not the concern of the publisher, and BizTalk shields the
service caller from these details.